{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Otto商品预测——PCA & SVM\n",
    "\n",
    "-\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 首先 import 必要的模块\n",
    "import pandas as pd \n",
    "import numpy as np\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 读取原始训练数据\n",
    "dpath = './Otto/data/'\n",
    "train = pd.read_csv(dpath +\"Otto_train.csv\")\n",
    "\n",
    "# 分割数据\n",
    "y_train = train['target']   \n",
    "X_train = train.drop([\"id\", \"target\"], axis=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# train.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "-\n",
    "\n",
    "\n",
    "### 🖱  问题1：观察Otto商品的特征进行PCA各维的方差，可以得到什么结论？\n",
    "\n",
    "\n",
    "    （1）原始数据方差"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>id</th>\n",
       "      <th>feat_1</th>\n",
       "      <th>feat_2</th>\n",
       "      <th>feat_3</th>\n",
       "      <th>feat_4</th>\n",
       "      <th>feat_5</th>\n",
       "      <th>feat_6</th>\n",
       "      <th>feat_7</th>\n",
       "      <th>feat_8</th>\n",
       "      <th>feat_9</th>\n",
       "      <th>...</th>\n",
       "      <th>feat_84</th>\n",
       "      <th>feat_85</th>\n",
       "      <th>feat_86</th>\n",
       "      <th>feat_87</th>\n",
       "      <th>feat_88</th>\n",
       "      <th>feat_89</th>\n",
       "      <th>feat_90</th>\n",
       "      <th>feat_91</th>\n",
       "      <th>feat_92</th>\n",
       "      <th>feat_93</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>count</th>\n",
       "      <td>61878.000000</td>\n",
       "      <td>61878.00000</td>\n",
       "      <td>61878.000000</td>\n",
       "      <td>61878.000000</td>\n",
       "      <td>61878.000000</td>\n",
       "      <td>61878.000000</td>\n",
       "      <td>61878.000000</td>\n",
       "      <td>61878.000000</td>\n",
       "      <td>61878.000000</td>\n",
       "      <td>61878.000000</td>\n",
       "      <td>...</td>\n",
       "      <td>61878.000000</td>\n",
       "      <td>61878.000000</td>\n",
       "      <td>61878.000000</td>\n",
       "      <td>61878.000000</td>\n",
       "      <td>61878.000000</td>\n",
       "      <td>61878.000000</td>\n",
       "      <td>61878.000000</td>\n",
       "      <td>61878.000000</td>\n",
       "      <td>61878.000000</td>\n",
       "      <td>61878.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>mean</th>\n",
       "      <td>30939.500000</td>\n",
       "      <td>0.38668</td>\n",
       "      <td>0.263066</td>\n",
       "      <td>0.901467</td>\n",
       "      <td>0.779081</td>\n",
       "      <td>0.071043</td>\n",
       "      <td>0.025696</td>\n",
       "      <td>0.193704</td>\n",
       "      <td>0.662433</td>\n",
       "      <td>1.011296</td>\n",
       "      <td>...</td>\n",
       "      <td>0.070752</td>\n",
       "      <td>0.532306</td>\n",
       "      <td>1.128576</td>\n",
       "      <td>0.393549</td>\n",
       "      <td>0.874915</td>\n",
       "      <td>0.457772</td>\n",
       "      <td>0.812421</td>\n",
       "      <td>0.264941</td>\n",
       "      <td>0.380119</td>\n",
       "      <td>0.126135</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>std</th>\n",
       "      <td>17862.784315</td>\n",
       "      <td>1.52533</td>\n",
       "      <td>1.252073</td>\n",
       "      <td>2.934818</td>\n",
       "      <td>2.788005</td>\n",
       "      <td>0.438902</td>\n",
       "      <td>0.215333</td>\n",
       "      <td>1.030102</td>\n",
       "      <td>2.255770</td>\n",
       "      <td>3.474822</td>\n",
       "      <td>...</td>\n",
       "      <td>1.151460</td>\n",
       "      <td>1.900438</td>\n",
       "      <td>2.681554</td>\n",
       "      <td>1.575455</td>\n",
       "      <td>2.115466</td>\n",
       "      <td>1.527385</td>\n",
       "      <td>4.597804</td>\n",
       "      <td>2.045646</td>\n",
       "      <td>0.982385</td>\n",
       "      <td>1.201720</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>min</th>\n",
       "      <td>1.000000</td>\n",
       "      <td>0.00000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>...</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25%</th>\n",
       "      <td>15470.250000</td>\n",
       "      <td>0.00000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>...</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>50%</th>\n",
       "      <td>30939.500000</td>\n",
       "      <td>0.00000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>...</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>75%</th>\n",
       "      <td>46408.750000</td>\n",
       "      <td>0.00000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>...</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>max</th>\n",
       "      <td>61878.000000</td>\n",
       "      <td>61.00000</td>\n",
       "      <td>51.000000</td>\n",
       "      <td>64.000000</td>\n",
       "      <td>70.000000</td>\n",
       "      <td>19.000000</td>\n",
       "      <td>10.000000</td>\n",
       "      <td>38.000000</td>\n",
       "      <td>76.000000</td>\n",
       "      <td>43.000000</td>\n",
       "      <td>...</td>\n",
       "      <td>76.000000</td>\n",
       "      <td>55.000000</td>\n",
       "      <td>65.000000</td>\n",
       "      <td>67.000000</td>\n",
       "      <td>30.000000</td>\n",
       "      <td>61.000000</td>\n",
       "      <td>130.000000</td>\n",
       "      <td>52.000000</td>\n",
       "      <td>19.000000</td>\n",
       "      <td>87.000000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>8 rows × 94 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "                 id       feat_1        feat_2        feat_3        feat_4  \\\n",
       "count  61878.000000  61878.00000  61878.000000  61878.000000  61878.000000   \n",
       "mean   30939.500000      0.38668      0.263066      0.901467      0.779081   \n",
       "std    17862.784315      1.52533      1.252073      2.934818      2.788005   \n",
       "min        1.000000      0.00000      0.000000      0.000000      0.000000   \n",
       "25%    15470.250000      0.00000      0.000000      0.000000      0.000000   \n",
       "50%    30939.500000      0.00000      0.000000      0.000000      0.000000   \n",
       "75%    46408.750000      0.00000      0.000000      0.000000      0.000000   \n",
       "max    61878.000000     61.00000     51.000000     64.000000     70.000000   \n",
       "\n",
       "             feat_5        feat_6        feat_7        feat_8        feat_9  \\\n",
       "count  61878.000000  61878.000000  61878.000000  61878.000000  61878.000000   \n",
       "mean       0.071043      0.025696      0.193704      0.662433      1.011296   \n",
       "std        0.438902      0.215333      1.030102      2.255770      3.474822   \n",
       "min        0.000000      0.000000      0.000000      0.000000      0.000000   \n",
       "25%        0.000000      0.000000      0.000000      0.000000      0.000000   \n",
       "50%        0.000000      0.000000      0.000000      0.000000      0.000000   \n",
       "75%        0.000000      0.000000      0.000000      1.000000      0.000000   \n",
       "max       19.000000     10.000000     38.000000     76.000000     43.000000   \n",
       "\n",
       "       ...       feat_84       feat_85       feat_86       feat_87  \\\n",
       "count  ...  61878.000000  61878.000000  61878.000000  61878.000000   \n",
       "mean   ...      0.070752      0.532306      1.128576      0.393549   \n",
       "std    ...      1.151460      1.900438      2.681554      1.575455   \n",
       "min    ...      0.000000      0.000000      0.000000      0.000000   \n",
       "25%    ...      0.000000      0.000000      0.000000      0.000000   \n",
       "50%    ...      0.000000      0.000000      0.000000      0.000000   \n",
       "75%    ...      0.000000      0.000000      1.000000      0.000000   \n",
       "max    ...     76.000000     55.000000     65.000000     67.000000   \n",
       "\n",
       "            feat_88       feat_89       feat_90       feat_91       feat_92  \\\n",
       "count  61878.000000  61878.000000  61878.000000  61878.000000  61878.000000   \n",
       "mean       0.874915      0.457772      0.812421      0.264941      0.380119   \n",
       "std        2.115466      1.527385      4.597804      2.045646      0.982385   \n",
       "min        0.000000      0.000000      0.000000      0.000000      0.000000   \n",
       "25%        0.000000      0.000000      0.000000      0.000000      0.000000   \n",
       "50%        0.000000      0.000000      0.000000      0.000000      0.000000   \n",
       "75%        1.000000      0.000000      0.000000      0.000000      0.000000   \n",
       "max       30.000000     61.000000    130.000000     52.000000     19.000000   \n",
       "\n",
       "            feat_93  \n",
       "count  61878.000000  \n",
       "mean       0.126135  \n",
       "std        1.201720  \n",
       "min        0.000000  \n",
       "25%        0.000000  \n",
       "50%        0.000000  \n",
       "75%        0.000000  \n",
       "max       87.000000  \n",
       "\n",
       "[8 rows x 94 columns]"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "train.describe()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "💬 **理解：** 此时，在原始特征上，Otto商品每个维度的方差，也就是 std 均在 0.2-4.8 之间，方差值都不大。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "    （2）PCA降维后的方差"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.decomposition import PCA\n",
    "\n",
    "pca = PCA(n_components = 0.999)\n",
    "pca.fit(X_train)\n",
    "\n",
    "X_train_pca = pca.transform(X_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.bar(range(len(pca.explained_variance_)), pca.explained_variance_)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([62.66160954, 45.8544168 , 34.00380894, 32.62247049, 23.46995581,\n",
       "       21.1316165 , 18.57234878, 16.76748689, 15.63870054, 14.61755928,\n",
       "       13.80363614, 11.84403114, 11.50726376, 10.48904317, 10.23350979,\n",
       "        9.90433393,  9.32504604,  9.07766365,  8.25020491,  7.52604241,\n",
       "        6.62371872,  6.29460358,  5.69675195,  5.41004497,  5.32673974,\n",
       "        4.94138953,  4.57782365,  4.39901475,  4.32428615,  3.99484425,\n",
       "        3.96112011,  3.74330413,  3.69404493,  3.58854956,  3.5037178 ,\n",
       "        3.33237745,  3.23143287,  3.17273102,  3.02698575,  2.91635437,\n",
       "        2.78996199,  2.64202083,  2.56246518,  2.50100637,  2.3907329 ,\n",
       "        2.15367577,  2.0950263 ,  2.05872626,  1.94560371,  1.82113464,\n",
       "        1.79071228,  1.67446039,  1.63775812,  1.58957057,  1.47173376,\n",
       "        1.45690223,  1.4021227 ,  1.33365684,  1.3026626 ,  1.257053  ,\n",
       "        1.24454309,  1.20509741,  1.17470384,  1.10330485,  1.07670305,\n",
       "        0.98651093,  0.96022255,  0.91868899,  0.90369727,  0.84794746,\n",
       "        0.81842326,  0.7664098 ,  0.76164154,  0.7151948 ,  0.69229289,\n",
       "        0.66054538,  0.64593473,  0.57503377,  0.5461002 ,  0.51595711,\n",
       "        0.49613646,  0.46609829,  0.45358607,  0.4293995 ,  0.40549925,\n",
       "        0.39428121,  0.36203599,  0.35199544,  0.28490418,  0.23773501])"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pca.explained_variance_"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "💬 **理解：** \n",
    "\n",
    "    此时，降维后的方差值差异非常大，最高的方差有62左右，而最低的方差值只有0.5几。  \n",
    "    这说明PCA降维，是可以保留原始数据变化最大的方向，能用较少的数据维度，保留较多的原始数据特性。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "-\n",
    "\n",
    "### 🖱  问题2：对Otto商品tfidf特征，进行PCA降维，给出各维方差的分布图  \n",
    "\n",
    "\n",
    "    （1）导入tf-idf数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 读取 tf-idf 训练数据\n",
    "data = pd.read_csv(dpath +\"Otto_FE_train_tfidf.csv\")\n",
    "# data.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "    （2）分割数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "y = data['target']   \n",
    "X = data.drop([\"id\", \"target\"], axis=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "    （3）PCA降维方差图"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "pca = PCA(n_components = 0.999)\n",
    "pca.fit(X_train)\n",
    "    \n",
    "X_train_pca = pca.transform(X_train)\n",
    "\n",
    "plt.bar(range(len(pca.explained_variance_)), pca.explained_variance_)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "-\n",
    "\n",
    "### 🖱  问题3：采用train_test_split，从数据集中随机抽取10000条记录，对这部分数据进行PCA降维，保留85%的能量  \n",
    "\n",
    "\n",
    "    （1）导入 org + tf-idf 数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 采用原始特征 + tf_idf特征\n",
    "train1 = pd.read_csv(dpath +\"Otto_FE_train_org.csv\")\n",
    "train2 = pd.read_csv(dpath +\"Otto_FE_train_tfidf.csv\")\n",
    "\n",
    "# 去掉多余的id\n",
    "train2 = train2.drop([\"id\",\"target\"], axis=1)\n",
    "train =  pd.concat([train1, train2], axis = 1, ignore_index=False)\n",
    "\n",
    "\n",
    "del train1\n",
    "del train2\n",
    "\n",
    "# train.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "    （2）分割数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(10000, 186)\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Users/apple/anaconda3/lib/python3.7/site-packages/sklearn/model_selection/_split.py:2179: FutureWarning: From version 0.21, test_size will always complement train_size unless both are specified.\n",
      "  FutureWarning)\n"
     ]
    }
   ],
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "y = train['target']\n",
    "X = train.drop([\"id\", \"target\"], axis=1)\n",
    "\n",
    "# 保存特征名字\n",
    "feat_names = X.columns \n",
    "\n",
    "# 从数据集中随机分割出10,000的样本作为训练集\n",
    "X_train, X_drop, y_train, y_drop = train_test_split(X, y, train_size=10000, random_state=10)\n",
    "print (X_train.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "    （3）PCA降维"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "pca = PCA(n_components = 0.85)\n",
    "pca.fit(X_train)\n",
    " \n",
    "X_train_pca = pca.transform(X_train)\n",
    "\n",
    "plt.bar(range(len(pca.explained_variance_)), pca.explained_variance_)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "-\n",
    "\n",
    "### 🖱  问题4：对以上降维后的数据，训练RBF核SVM，并对超参数调优，把训练结果与原始数据的情况进行比较  \n",
    "\n",
    "\n",
    "    （1）保存上述降维结果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 保存PCA特征变换结果\n",
    "n_components = pca.n_components_\n",
    "feat_names_pca = []\n",
    "\n",
    "for i in range(n_components):\n",
    "    feat_names_pca.append(\"pca_\" + str(i))\n",
    "\n",
    "\n",
    "y = pd.Series(data = y_train, name = 'target')\n",
    "X = pd.DataFrame(columns = feat_names_pca, data = X_train_pca, index=y.index)\n",
    "train_id = pd.Series(data = y.index, name = 'id', index=y.index)\n",
    "\n",
    "train_pca = pd.concat([train_id, X, y], axis = 1)\n",
    "train_pca.to_csv('Otto_FE_train_PCA_org_tfidf.csv',index=False, header=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "    （2）导入数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(10000, 55)\n"
     ]
    }
   ],
   "source": [
    "# 采用 降维 的原始特征 + tf_idf特征\n",
    "train = pd.read_csv(\"Otto_FE_train_PCA_org_tfidf.csv\")\n",
    "print (train.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "    （3）分割数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "y = train['target']\n",
    "X = train.drop([\"id\", \"target\"], axis=1)\n",
    "\n",
    "# 保存特征名字\n",
    "feat_names = X.columns \n",
    "\n",
    "\n",
    "from scipy.sparse import csr_matrix\n",
    "X = csr_matrix(X)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "    （4）rbf-SVM"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Users/apple/anaconda3/lib/python3.7/site-packages/sklearn/svm/base.py:244: ConvergenceWarning: Solver terminated early (max_iter=5000).  Consider pre-processing your data with StandardScaler or MinMaxScaler.\n",
      "  % self.max_iter, ConvergenceWarning)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "GridSearchCV(cv=5, error_score='raise-deprecating',\n",
       "       estimator=SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,\n",
       "  decision_function_shape='ovr', degree=3, gamma='auto_deprecated',\n",
       "  kernel='rbf', max_iter=5000, probability=False, random_state=None,\n",
       "  shrinking=True, tol=0.001, verbose=False),\n",
       "       fit_params=None, iid='warn', n_jobs=None,\n",
       "       param_grid={'C': [0.01, 0.1, 1, 10, 100], 'gamma': [0.0001, 0.001, 0.01, 0.1, 1]},\n",
       "       pre_dispatch='2*n_jobs', refit=True, return_train_score='warn',\n",
       "       scoring=None, verbose=0)"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.svm import SVC\n",
    "from sklearn.model_selection import GridSearchCV\n",
    "\n",
    "\n",
    "Cs = [ 0.01, 0.1, 1, 10, 100]\n",
    "gammas = [0.0001, 0.001, 0.01, 0.1, 1]\n",
    "\n",
    "param_grid = {'C': Cs, 'gamma': gammas}\n",
    "svc_rbf =  SVC( kernel='rbf', max_iter=5000)\n",
    "grid = GridSearchCV( svc_rbf, param_grid, cv=5)\n",
    "\n",
    "grid.fit(X, y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.7828\n",
      "{'C': 10, 'gamma': 1}\n"
     ]
    }
   ],
   "source": [
    "print(grid.best_score_)\n",
    "print(grid.best_params_)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "    （5）在不同正则参数C和核函数宽度gamma下，对应的正确率曲线  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# plot误差曲线\n",
    "test_means = grid.cv_results_['mean_test_score']\n",
    "test_stds = grid.cv_results_['std_test_score']\n",
    "\n",
    "# plot results\n",
    "n_Cs = len(Cs)\n",
    "number_gamms = len(gammas)\n",
    "\n",
    "test_scores = np.array(test_means).reshape(n_Cs, number_gamms)\n",
    "test_stds = np.array(test_stds).reshape(n_Cs, number_gamms)\n",
    "\n",
    "x_axis = np.log10(Cs)\n",
    "for i, value in enumerate(gammas):\n",
    "    plt.plot(x_axis, test_scores[:, i], label=gammas[i])\n",
    "\n",
    "\n",
    "plt.legend()\n",
    "plt.xlabel( 'log(C)' )                                                                                                      \n",
    "plt.ylabel( 'accuracy' )\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 原始 org+tfidf：\n",
    "    \n",
    "        正确率：0.7883\n",
    "        最佳超参数：{'C': 10, 'gamma': 1}\n",
    "\n",
    "- 降维 org+tfidf：\n",
    "\n",
    "        正确率：0.7828\n",
    "        最佳超参数：{'C': 10, 'gamma': 1}\n",
    "        \n",
    "啊，降维后的正确率没有之前的高，但是差异也不是很大，才0.006左右，可以接受。而且，降维后的数据用来训练模型的速度快了不少，用少量的精度换取时间的缩短，感觉还是值得的。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
